home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 15232 < prev    next >
Encoding:
Text File  |  1996-08-05  |  3.6 KB  |  116 lines

  1. Path: news.primenet.com!jstern
  2. From: jstern@Primenet.Com (Josh Stern)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Templates, Pointers to Members and Static Initialization
  5. Date: 3 Apr 1996 03:41:00 -0700
  6. Organization: Primenet Services for the Internet
  7. Sender: root@primenet.com
  8. Message-ID: <4jtkjs$8se@nnrp1.news.primenet.com>
  9. References: <4jp0bd$2h7@blue.usps.gov>
  10. X-Posted-By: jstern@usr6.primenet.com
  11.  
  12. Bill Seymour  <wseymour@email.usps.gov> wrote:
  13. >I need to create a static const associative array of descriptors for
  14. >members of arbitrary structures.  It's known that all members will have
  15. >type char[] and contain null-terminated strings.  My first idea for one
  16. >element of such an array is:
  17. >
  18. >    struct MemberDescriptor
  19. >    {
  20. >        const char* name;
  21. >        ptrdiff_t offset;
  22. >        size_t size;
  23. >        char* GetString(void* str) const { return (char*)str + offset; }
  24. >    };
  25. >
  26. >but offset can't be statically initialized without an offsetof operator.
  27. >(Magic numbers are out of the question, of course; and a macro that
  28. >expands to the difference between two pointers isn't a constant.)
  29.  
  30. I'm not sure of exactly what you are trying to do, but
  31. I think that your best bet would go like this:
  32.  
  33. 1) if you know exactly how many of these 'elements' you have then
  34. declare this as a const int (in whatever scope/namespace is
  35. appropriate);  otherwise, pick some dummy value for the record
  36. and let that act like '\0' for strings - i.e. put the dummy
  37. value last in your initializer list so when you get to it
  38. you know that is the end.
  39.  
  40. 2) build a dynamic associative map using the array from
  41. one - this can still be a static global variable so long
  42. as it takes such an array as an initializer.  Here is
  43. a rough sketch assuming the 'unknown' case from 1) - I'll
  44. use STL's map container:
  45.  
  46. #include <map.h>
  47. #include <string.h>
  48.  
  49. struct MemberDescriptor 
  50. {
  51. const char* name;
  52. const char* SomeOtherThing; // just for concreteness
  53.                                                           // put whatever info here
  54. };
  55.  
  56. // Really, it would be better to use a String class instead of const char*
  57.  
  58. MemberDescriptor Data[] = { {"Name1", "description1"}, \
  59.                            {"Name2", "description2"}, \
  60.                            {"Name3", "description3"}, \
  61.                            {"END",""} };  // "END" is special value
  62.  
  63. struct STRC { // Comparator required for map
  64. bool operator()  (const char* x, const char* y) const {
  65.    return (strcmp(x,y) < 0);
  66. }
  67. };
  68.  
  69. class ArrMap {
  70. public:
  71. typedef map<const char* const,const char*, STRC > mp; // all work done here
  72. typedef mp::iterator iterator;
  73. protected: 
  74. mp m;
  75. public:
  76.   ArrMap(MemberDescriptor* yourdata) : m() {  // constructor fills map
  77.      MemberDescriptor* tptr = yourdata;
  78.       const char* str;
  79.       while (strcmp((str = tptr->name),"END")) {
  80.          m[str] = tptr++->SomeOtherThing;
  81.      }
  82.    }
  83.   const char*& operator[](const char*& x) { return m[x]; }
  84.  
  85. // Duplicate rest of interface to map, including operator[], or see below
  86. };
  87.  
  88. /* Rather than having the map as a member of ArrMap it would
  89. be more convenient to have ArrMap as a derived class, but initializing
  90. it as a static object would then involve special purpose iterators
  91. that I didn't want to bother to write in.
  92. */
  93.  
  94.  
  95. ArrMap  yourmap(Data);  
  96.  
  97. // Testing...(not very creatively)
  98. void main(void)
  99. {
  100.    cout << '\n' << yourmap["Name1"] <<  '\n' 
  101.            << yourmap["Name2"] << '\n'
  102.             << yourmap["Name3"] << '\n';
  103.              
  104. }
  105.  
  106. /****************************************************/
  107.  
  108. - Josh
  109.  
  110.  
  111. --
  112. -------------------------------------------------------------------------------
  113. jstern
  114. jstern@primenet.com
  115. -------------------------------------------------------------------------------
  116.